package org.japo.java.jdbc.samples;

import java.awt.Color;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeListener;
import org.apache.commons.beanutils.BeanUtils;
import org.japo.java.entities.Alumno;
import org.japo.java.entities.EnlaceBD;
import sun.awt.image.ToolkitImage;

/**
 *
 * @author José A. Pacheco Ondoño - joanpaon@gmail.com
 */
public class GestionAlumnos extends javax.swing.JFrame {
    // ---

    // Bean de enlace para los controles del formulario
    private Alumno alumno;

    // Dialogo de conexión
    DlgEnlaceBD dialogoCon;

    // Memoria para la carpeta de imágenes
    private File carpetaIMG;

    // Referencias para la gestión de la base de datos
    private Connection con;
    private Statement stmt;
    private ResultSet rs;

    // Semaforos de validación
    private boolean expOK;
    private boolean nombreOK;
    private boolean apellidosOK;
    private boolean nacOK;
    private boolean nifOK;
    private boolean telefonoOK;
    private boolean emailOK;
    private boolean domicilioOK;
    private boolean localidadOK;
    private boolean provinciaOK;
    private boolean cpOK;
    private boolean userOK;
    private boolean passOK;

    // Expresiones regulares de validación
    private final String ER_EXP = "[0-9]{1,5}";
    private final String ER_NOMBRE = ".{3,50}";
    private final String ER_APELLIDOS = ".{3,50}";
    private final String ER_NAC = "[0-9]{1,2}/[0-9]{1,2}/[0-9]{1,4}";
    private final String ER_NIF = "[0-9]{8}-[A-Z]";
    private final String ER_TELEFONO = "[0-9]{9}";
    private final String ER_MAIL = ".{0,50}";
    private final String ER_DOMICILIO = ".{0,50}";
    private final String ER_LOCALIDAD = ".{0,50}";
    private final String ER_PROVINCIA = ".{0,50}";
    private final String ER_CP = "[0-9]{5}";
    private final String ER_USER = ".{1,20}";
    private final String ER_PASS = ".{0,20}";

    // MouseListeners
    MouseListener[] listaML = null;

    public GestionAlumnos() {
        iniciarAnterior();
        initComponents();
        iniciarPosterior();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();

        pnlId = new javax.swing.JPanel();
        lblExp = new javax.swing.JLabel();
        lblNif = new javax.swing.JLabel();
        lblNombre = new javax.swing.JLabel();
        lblApellidos = new javax.swing.JLabel();
        lblNac = new javax.swing.JLabel();
        lblTelefono = new javax.swing.JLabel();
        lblEMail = new javax.swing.JLabel();
        txfExp = new javax.swing.JTextField();
        txfNif = new javax.swing.JTextField();
        txfNombre = new javax.swing.JTextField();
        txfApellidos = new javax.swing.JTextField();
        txfNac = new javax.swing.JTextField();
        txfTelefono = new javax.swing.JTextField();
        txfEMail = new javax.swing.JTextField();
        lblFoto = new javax.swing.JLabel();
        pnlDomicilio = new javax.swing.JPanel();
        lblDomicilio = new javax.swing.JLabel();
        lblLocalidad = new javax.swing.JLabel();
        txfLocalidad = new javax.swing.JTextField();
        txfDomicilio = new javax.swing.JTextField();
        txfCP = new javax.swing.JTextField();
        lblCP = new javax.swing.JLabel();
        txfProvincia = new javax.swing.JTextField();
        lblProvincia = new javax.swing.JLabel();
        pnlSeguridad = new javax.swing.JPanel();
        lblUser = new javax.swing.JLabel();
        txfUser = new javax.swing.JTextField();
        lblPass = new javax.swing.JLabel();
        pwfPass = new javax.swing.JPasswordField();
        pnlNavegacion = new javax.swing.JPanel();
        btnIni = new javax.swing.JButton();
        btnAnt = new javax.swing.JButton();
        btnAct = new javax.swing.JButton();
        btnIns = new javax.swing.JButton();
        btnBor = new javax.swing.JButton();
        btnSig = new javax.swing.JButton();
        btnFin = new javax.swing.JButton();
        sldRegAct = new javax.swing.JSlider();
        lblRegAct = new javax.swing.JLabel();
        lblNumReg = new javax.swing.JLabel();
        btnConDes = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Gestión de alumnos");
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        pnlId.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Identificación", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("SansSerif", 0, 14))); // NOI18N

        lblExp.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        lblExp.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        lblExp.setText("Expediente");
        lblExp.setMaximumSize(new java.awt.Dimension(90, 30));
        lblExp.setMinimumSize(new java.awt.Dimension(90, 30));
        lblExp.setPreferredSize(new java.awt.Dimension(90, 30));

        lblNif.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        lblNif.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        lblNif.setText("NIF");
        lblNif.setMaximumSize(new java.awt.Dimension(70, 38));
        lblNif.setMinimumSize(new java.awt.Dimension(70, 100));
        lblNif.setPreferredSize(new java.awt.Dimension(60, 38));

        lblNombre.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        lblNombre.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        lblNombre.setText("Nombre");
        lblNombre.setMaximumSize(new java.awt.Dimension(90, 30));
        lblNombre.setMinimumSize(new java.awt.Dimension(90, 30));
        lblNombre.setPreferredSize(new java.awt.Dimension(90, 30));

        lblApellidos.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        lblApellidos.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        lblApellidos.setText("Apellidos");
        lblApellidos.setMaximumSize(new java.awt.Dimension(90, 30));
        lblApellidos.setMinimumSize(new java.awt.Dimension(90, 30));
        lblApellidos.setPreferredSize(new java.awt.Dimension(90, 30));

        lblNac.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        lblNac.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        lblNac.setText("Nacimiento");
        lblNac.setMaximumSize(new java.awt.Dimension(90, 30));
        lblNac.setMinimumSize(new java.awt.Dimension(90, 30));
        lblNac.setPreferredSize(new java.awt.Dimension(90, 30));

        lblTelefono.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        lblTelefono.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        lblTelefono.setText("Teléfono");
        lblTelefono.setMaximumSize(new java.awt.Dimension(70, 14));
        lblTelefono.setMinimumSize(new java.awt.Dimension(70, 14));
        lblTelefono.setPreferredSize(new java.awt.Dimension(90, 30));

        lblEMail.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        lblEMail.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        lblEMail.setText("EMail");
        lblEMail.setMaximumSize(new java.awt.Dimension(90, 30));
        lblEMail.setMinimumSize(new java.awt.Dimension(90, 30));
        lblEMail.setPreferredSize(new java.awt.Dimension(90, 30));

        txfExp.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        txfExp.setEnabled(false);
        txfExp.setMaximumSize(new java.awt.Dimension(70, 30));
        txfExp.setMinimumSize(new java.awt.Dimension(70, 30));
        txfExp.setPreferredSize(new java.awt.Dimension(90, 30));

        org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${alumno.exp}"), txfExp, org.jdesktop.beansbinding.BeanProperty.create("text_ON_FOCUS_LOST"), "exp");
        bindingGroup.addBinding(binding);

        txfExp.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                txfExpFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                txfExpFocusLost(evt);
            }
        });

        txfNif.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        txfNif.setEnabled(false);
        txfNif.setMaximumSize(new java.awt.Dimension(70, 30));
        txfNif.setMinimumSize(new java.awt.Dimension(70, 30));
        txfNif.setPreferredSize(new java.awt.Dimension(90, 30));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${alumno.nif}"), txfNif, org.jdesktop.beansbinding.BeanProperty.create("text_ON_FOCUS_LOST"), "nif");
        bindingGroup.addBinding(binding);

        txfNif.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                txfNifFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                txfNifFocusLost(evt);
            }
        });

        txfNombre.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        txfNombre.setEnabled(false);
        txfNombre.setMaximumSize(new java.awt.Dimension(70, 30));
        txfNombre.setMinimumSize(new java.awt.Dimension(70, 30));
        txfNombre.setPreferredSize(new java.awt.Dimension(90, 30));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${alumno.nombre}"), txfNombre, org.jdesktop.beansbinding.BeanProperty.create("text_ON_FOCUS_LOST"), "nombre");
        bindingGroup.addBinding(binding);

        txfNombre.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                txfNombreFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                txfNombreFocusLost(evt);
            }
        });

        txfApellidos.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        txfApellidos.setAutoscrolls(false);
        txfApellidos.setEnabled(false);
        txfApellidos.setMaximumSize(new java.awt.Dimension(70, 30));
        txfApellidos.setMinimumSize(new java.awt.Dimension(70, 30));
        txfApellidos.setPreferredSize(new java.awt.Dimension(90, 30));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${alumno.apellidos}"), txfApellidos, org.jdesktop.beansbinding.BeanProperty.create("text_ON_FOCUS_LOST"), "apellidos");
        bindingGroup.addBinding(binding);

        txfApellidos.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                txfApellidosFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                txfApellidosFocusLost(evt);
            }
        });

        txfNac.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        txfNac.setEnabled(false);
        txfNac.setMaximumSize(new java.awt.Dimension(70, 30));
        txfNac.setMinimumSize(new java.awt.Dimension(70, 30));
        txfNac.setPreferredSize(new java.awt.Dimension(90, 30));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${alumno.nac}"), txfNac, org.jdesktop.beansbinding.BeanProperty.create("text_ON_FOCUS_LOST"), "nac");
        bindingGroup.addBinding(binding);

        txfNac.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                txfNacFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                txfNacFocusLost(evt);
            }
        });

        txfTelefono.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        txfTelefono.setEnabled(false);
        txfTelefono.setMaximumSize(new java.awt.Dimension(70, 30));
        txfTelefono.setMinimumSize(new java.awt.Dimension(70, 30));
        txfTelefono.setPreferredSize(new java.awt.Dimension(90, 30));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${alumno.telefono}"), txfTelefono, org.jdesktop.beansbinding.BeanProperty.create("text_ON_FOCUS_LOST"), "telefono");
        bindingGroup.addBinding(binding);

        txfTelefono.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                txfTelefonoFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                txfTelefonoFocusLost(evt);
            }
        });

        txfEMail.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        txfEMail.setEnabled(false);
        txfEMail.setMaximumSize(new java.awt.Dimension(70, 30));
        txfEMail.setMinimumSize(new java.awt.Dimension(70, 30));
        txfEMail.setPreferredSize(new java.awt.Dimension(90, 30));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${alumno.email}"), txfEMail, org.jdesktop.beansbinding.BeanProperty.create("text_ON_FOCUS_LOST"), "email");
        bindingGroup.addBinding(binding);

        txfEMail.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                txfEMailFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                txfEMailFocusLost(evt);
            }
        });

        lblFoto.setBackground(new java.awt.Color(255, 255, 255));
        lblFoto.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblFoto.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/japo/java/resources/images/alguien.png"))); // NOI18N
        lblFoto.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED));
        lblFoto.setEnabled(false);
        lblFoto.setMaximumSize(new java.awt.Dimension(116, 143));
        lblFoto.setMinimumSize(new java.awt.Dimension(116, 143));
        lblFoto.setOpaque(true);
        lblFoto.setPreferredSize(new java.awt.Dimension(116, 143));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${alumno.foto}"), lblFoto, org.jdesktop.beansbinding.BeanProperty.create("icon"));
        bindingGroup.addBinding(binding);

        lblFoto.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                lblFotoMouseClicked(evt);
            }
        });

        javax.swing.GroupLayout pnlIdLayout = new javax.swing.GroupLayout(pnlId);
        pnlId.setLayout(pnlIdLayout);
        pnlIdLayout.setHorizontalGroup(
            pnlIdLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlIdLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlIdLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(lblExp, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(lblNombre, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(lblApellidos, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(lblNac, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(lblEMail, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlIdLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(txfEMail, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, pnlIdLayout.createSequentialGroup()
                        .addComponent(txfNac, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(lblTelefono, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(txfTelefono, javax.swing.GroupLayout.PREFERRED_SIZE, 220, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(txfApellidos, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(txfNombre, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(pnlIdLayout.createSequentialGroup()
                        .addComponent(txfExp, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(lblNif, javax.swing.GroupLayout.PREFERRED_SIZE, 76, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(txfNif, javax.swing.GroupLayout.PREFERRED_SIZE, 129, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(lblFoto, javax.swing.GroupLayout.PREFERRED_SIZE, 132, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        pnlIdLayout.setVerticalGroup(
            pnlIdLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlIdLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlIdLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(lblFoto, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, pnlIdLayout.createSequentialGroup()
                        .addGroup(pnlIdLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(lblExp, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(txfExp, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(txfNif, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(lblNif, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(pnlIdLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(lblNombre, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(txfNombre, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(pnlIdLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(txfApellidos, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(lblApellidos, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(pnlIdLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(txfTelefono, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(lblTelefono, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(txfNac, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(lblNac, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(pnlIdLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(txfEMail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(lblEMail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pnlIdLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {lblApellidos, lblEMail, lblExp, lblNac, lblTelefono, txfApellidos, txfEMail});

        pnlIdLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {txfNif, txfTelefono});

        pnlDomicilio.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Domicilio", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("SansSerif", 0, 14))); // NOI18N

        lblDomicilio.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        lblDomicilio.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        lblDomicilio.setText("Domicilio");
        lblDomicilio.setMaximumSize(new java.awt.Dimension(90, 30));
        lblDomicilio.setMinimumSize(new java.awt.Dimension(90, 30));
        lblDomicilio.setPreferredSize(new java.awt.Dimension(90, 30));

        lblLocalidad.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        lblLocalidad.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        lblLocalidad.setText("Localidad");
        lblLocalidad.setMaximumSize(new java.awt.Dimension(90, 30));
        lblLocalidad.setMinimumSize(new java.awt.Dimension(90, 30));
        lblLocalidad.setPreferredSize(new java.awt.Dimension(90, 30));

        txfLocalidad.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        txfLocalidad.setAutoscrolls(false);
        txfLocalidad.setEnabled(false);
        txfLocalidad.setMaximumSize(new java.awt.Dimension(70, 38));
        txfLocalidad.setMinimumSize(new java.awt.Dimension(70, 100));
        txfLocalidad.setPreferredSize(new java.awt.Dimension(90, 30));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${alumno.localidad}"), txfLocalidad, org.jdesktop.beansbinding.BeanProperty.create("text_ON_FOCUS_LOST"), "localidad");
        bindingGroup.addBinding(binding);

        txfLocalidad.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                txfLocalidadFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                txfLocalidadFocusLost(evt);
            }
        });

        txfDomicilio.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        txfDomicilio.setAutoscrolls(false);
        txfDomicilio.setEnabled(false);
        txfDomicilio.setMaximumSize(new java.awt.Dimension(70, 38));
        txfDomicilio.setMinimumSize(new java.awt.Dimension(70, 100));
        txfDomicilio.setPreferredSize(new java.awt.Dimension(90, 30));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${alumno.domicilio}"), txfDomicilio, org.jdesktop.beansbinding.BeanProperty.create("text_ON_FOCUS_LOST"), "domicilio");
        bindingGroup.addBinding(binding);

        txfDomicilio.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                txfDomicilioFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                txfDomicilioFocusLost(evt);
            }
        });

        txfCP.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        txfCP.setAutoscrolls(false);
        txfCP.setEnabled(false);
        txfCP.setMaximumSize(new java.awt.Dimension(70, 38));
        txfCP.setMinimumSize(new java.awt.Dimension(70, 100));
        txfCP.setPreferredSize(new java.awt.Dimension(90, 30));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${alumno.cp}"), txfCP, org.jdesktop.beansbinding.BeanProperty.create("text_ON_FOCUS_LOST"), "cp");
        bindingGroup.addBinding(binding);

        txfCP.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                txfCPFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                txfCPFocusLost(evt);
            }
        });

        lblCP.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        lblCP.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        lblCP.setText("C Postal");
        lblCP.setMaximumSize(new java.awt.Dimension(90, 38));
        lblCP.setMinimumSize(new java.awt.Dimension(90, 38));
        lblCP.setPreferredSize(new java.awt.Dimension(90, 30));

        txfProvincia.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        txfProvincia.setAutoscrolls(false);
        txfProvincia.setEnabled(false);
        txfProvincia.setMaximumSize(new java.awt.Dimension(70, 38));
        txfProvincia.setMinimumSize(new java.awt.Dimension(70, 100));
        txfProvincia.setPreferredSize(new java.awt.Dimension(90, 30));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${alumno.provincia}"), txfProvincia, org.jdesktop.beansbinding.BeanProperty.create("text_ON_FOCUS_LOST"), "provincia");
        bindingGroup.addBinding(binding);

        txfProvincia.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                txfProvinciaFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                txfProvinciaFocusLost(evt);
            }
        });

        lblProvincia.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        lblProvincia.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        lblProvincia.setText("Provincia");
        lblProvincia.setMaximumSize(new java.awt.Dimension(90, 30));
        lblProvincia.setMinimumSize(new java.awt.Dimension(90, 30));
        lblProvincia.setPreferredSize(new java.awt.Dimension(90, 30));

        javax.swing.GroupLayout pnlDomicilioLayout = new javax.swing.GroupLayout(pnlDomicilio);
        pnlDomicilio.setLayout(pnlDomicilioLayout);
        pnlDomicilioLayout.setHorizontalGroup(
            pnlDomicilioLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlDomicilioLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlDomicilioLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(pnlDomicilioLayout.createSequentialGroup()
                        .addComponent(lblDomicilio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(txfDomicilio, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(pnlDomicilioLayout.createSequentialGroup()
                        .addComponent(lblLocalidad, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(txfLocalidad, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(pnlDomicilioLayout.createSequentialGroup()
                        .addComponent(lblProvincia, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(txfProvincia, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(lblCP, javax.swing.GroupLayout.PREFERRED_SIZE, 99, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(txfCP, javax.swing.GroupLayout.PREFERRED_SIZE, 106, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        pnlDomicilioLayout.setVerticalGroup(
            pnlDomicilioLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlDomicilioLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlDomicilioLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblDomicilio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txfDomicilio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlDomicilioLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblLocalidad, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txfLocalidad, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlDomicilioLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblProvincia, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txfProvincia, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lblCP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txfCP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        pnlSeguridad.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Seguridad", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("SansSerif", 0, 14))); // NOI18N
        pnlSeguridad.setMaximumSize(new java.awt.Dimension(557, 118));
        pnlSeguridad.setMinimumSize(new java.awt.Dimension(557, 118));
        pnlSeguridad.setPreferredSize(new java.awt.Dimension(557, 118));

        lblUser.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        lblUser.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        lblUser.setText("Usuario");
        lblUser.setMaximumSize(new java.awt.Dimension(70, 14));
        lblUser.setMinimumSize(new java.awt.Dimension(70, 14));
        lblUser.setPreferredSize(new java.awt.Dimension(90, 30));

        txfUser.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        txfUser.setEnabled(false);
        txfUser.setPreferredSize(new java.awt.Dimension(90, 30));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${alumno.user}"), txfUser, org.jdesktop.beansbinding.BeanProperty.create("text_ON_FOCUS_LOST"), "user");
        bindingGroup.addBinding(binding);

        txfUser.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                txfUserFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                txfUserFocusLost(evt);
            }
        });

        lblPass.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        lblPass.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        lblPass.setText("Password");
        lblPass.setMaximumSize(new java.awt.Dimension(70, 14));
        lblPass.setMinimumSize(new java.awt.Dimension(70, 14));
        lblPass.setPreferredSize(new java.awt.Dimension(90, 30));

        pwfPass.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        pwfPass.setEnabled(false);
        pwfPass.setPreferredSize(new java.awt.Dimension(90, 30));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${alumno.pass}"), pwfPass, org.jdesktop.beansbinding.BeanProperty.create("text_ON_FOCUS_LOST"), "pass");
        bindingGroup.addBinding(binding);

        pwfPass.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                pwfPassFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                pwfPassFocusLost(evt);
            }
        });

        javax.swing.GroupLayout pnlSeguridadLayout = new javax.swing.GroupLayout(pnlSeguridad);
        pnlSeguridad.setLayout(pnlSeguridadLayout);
        pnlSeguridadLayout.setHorizontalGroup(
            pnlSeguridadLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlSeguridadLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lblUser, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(txfUser, javax.swing.GroupLayout.PREFERRED_SIZE, 226, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(lblPass, javax.swing.GroupLayout.DEFAULT_SIZE, 125, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pwfPass, javax.swing.GroupLayout.PREFERRED_SIZE, 247, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        pnlSeguridadLayout.setVerticalGroup(
            pnlSeguridadLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlSeguridadLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlSeguridadLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblUser, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txfUser, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(pwfPass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lblPass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pnlSeguridadLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {lblPass, lblUser, pwfPass, txfUser});

        pnlNavegacion.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Navegación", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("SansSerif", 0, 14))); // NOI18N
        pnlNavegacion.setMaximumSize(new java.awt.Dimension(557, 127));
        pnlNavegacion.setMinimumSize(new java.awt.Dimension(557, 127));
        pnlNavegacion.setPreferredSize(new java.awt.Dimension(557, 127));

        btnIni.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        btnIni.setText("<<");
        btnIni.setEnabled(false);
        btnIni.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnIniActionPerformed(evt);
            }
        });

        btnAnt.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        btnAnt.setText("<");
        btnAnt.setEnabled(false);
        btnAnt.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAntActionPerformed(evt);
            }
        });

        btnAct.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        btnAct.setText("Actualizar");
        btnAct.setEnabled(false);
        btnAct.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnActActionPerformed(evt);
            }
        });

        btnIns.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        btnIns.setText("Insertar");
        btnIns.setEnabled(false);
        btnIns.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnInsActionPerformed(evt);
            }
        });

        btnBor.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        btnBor.setText("Borrar");
        btnBor.setEnabled(false);
        btnBor.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnBorActionPerformed(evt);
            }
        });

        btnSig.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        btnSig.setText(">");
        btnSig.setEnabled(false);
        btnSig.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSigActionPerformed(evt);
            }
        });

        btnFin.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        btnFin.setText(">>");
        btnFin.setEnabled(false);
        btnFin.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnFinActionPerformed(evt);
            }
        });

        sldRegAct.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        sldRegAct.setMaximum(0);
        sldRegAct.setEnabled(false);
        sldRegAct.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sldRegActStateChanged(evt);
            }
        });

        lblRegAct.setBackground(new java.awt.Color(255, 255, 255));
        lblRegAct.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        lblRegAct.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblRegAct.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        lblRegAct.setEnabled(false);
        lblRegAct.setPreferredSize(new java.awt.Dimension(40, 28));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, sldRegAct, org.jdesktop.beansbinding.ELProperty.create("${value}"), lblRegAct, org.jdesktop.beansbinding.BeanProperty.create("text"));
        bindingGroup.addBinding(binding);

        lblNumReg.setBackground(new java.awt.Color(255, 255, 255));
        lblNumReg.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        lblNumReg.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblNumReg.setText("0");
        lblNumReg.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        lblNumReg.setEnabled(false);
        lblNumReg.setPreferredSize(new java.awt.Dimension(40, 28));

        btnConDes.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
        btnConDes.setText("Conectar");
        btnConDes.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnConDesActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout pnlNavegacionLayout = new javax.swing.GroupLayout(pnlNavegacion);
        pnlNavegacion.setLayout(pnlNavegacionLayout);
        pnlNavegacionLayout.setHorizontalGroup(
            pnlNavegacionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlNavegacionLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlNavegacionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(pnlNavegacionLayout.createSequentialGroup()
                        .addComponent(btnIni, javax.swing.GroupLayout.PREFERRED_SIZE, 77, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnAnt)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(pnlNavegacionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(btnIns, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(btnBor, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(btnAct, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                    .addGroup(pnlNavegacionLayout.createSequentialGroup()
                        .addComponent(sldRegAct, javax.swing.GroupLayout.DEFAULT_SIZE, 450, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(lblRegAct, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(lblNumReg, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlNavegacionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(pnlNavegacionLayout.createSequentialGroup()
                        .addComponent(btnSig)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnFin))
                    .addComponent(btnConDes, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );

        pnlNavegacionLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {btnAnt, btnFin, btnIni, btnSig});

        pnlNavegacionLayout.setVerticalGroup(
            pnlNavegacionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlNavegacionLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlNavegacionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(btnIni, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, pnlNavegacionLayout.createSequentialGroup()
                        .addComponent(btnAct)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnIns)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnBor))
                    .addComponent(btnAnt, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(btnFin, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(btnSig, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(pnlNavegacionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(sldRegAct, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lblRegAct, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lblNumReg, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btnConDes))
                .addContainerGap())
        );

        pnlNavegacionLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {btnConDes, lblNumReg, lblRegAct, sldRegAct});

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(pnlDomicilio, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(pnlSeguridad, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 746, Short.MAX_VALUE)
                    .addComponent(pnlNavegacion, javax.swing.GroupLayout.DEFAULT_SIZE, 746, Short.MAX_VALUE)
                    .addComponent(pnlId, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(pnlId, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pnlDomicilio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pnlSeguridad, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pnlNavegacion, javax.swing.GroupLayout.PREFERRED_SIZE, 213, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        bindingGroup.bind();

        pack();
        setLocationRelativeTo(null);
    }// </editor-fold>//GEN-END:initComponents

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        cerrarBD();
    }//GEN-LAST:event_formWindowClosing

    private void btnFinActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFinActionPerformed
        try {
            if (rs.last()) {
                actualizarInterfaz();
            }
        } catch (SQLException sqle) {
            System.out.println("Fin: " + sqle);
        }
    }//GEN-LAST:event_btnFinActionPerformed

    private void btnSigActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSigActionPerformed
        try {
            if (rs.next()) {
                actualizarInterfaz();
            }
        } catch (SQLException sqle) {
            System.out.println("Sig: " + sqle);
        }
    }//GEN-LAST:event_btnSigActionPerformed

    private void btnBorActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnBorActionPerformed
        // Muestra diálogo de confirmación
        int respuesta = JOptionPane.showConfirmDialog(this,
                "Borrar los datos actuales",
                "Borrar registro",
                JOptionPane.OK_CANCEL_OPTION,
                JOptionPane.WARNING_MESSAGE);

        if (respuesta == JOptionPane.OK_OPTION) {
            try {
                // Borrar la fila actual
                borrarFila(rs);

                // Actualizar interfaz
                actualizarInterfaz();
            } catch (Exception e) {
                JOptionPane.showMessageDialog(this,
                        "Actualización de datos cancelada");
            }
        }
    }//GEN-LAST:event_btnBorActionPerformed

    private void btnInsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnInsActionPerformed
        // Proceso de inserción
        if (comprobarValidez()) {
            int respuesta = JOptionPane.showConfirmDialog(this,
                    "Insertar los datos actuales",
                    "Insertar registro",
                    JOptionPane.OK_CANCEL_OPTION,
                    JOptionPane.WARNING_MESSAGE);

            if (respuesta == JOptionPane.OK_OPTION) {
                try {
                    // Insertar la fila actual
                    insertarFila(rs);

                    // Actualizar interfaz
                    actualizarInterfaz();
                } catch (SQLException e) {
                    JOptionPane.showMessageDialog(this,
                            "Inserción de datos cancelada");
                }
            }
        } else {
            JOptionPane.showMessageDialog(this, "Hay datos erróneos");
        }
    }//GEN-LAST:event_btnInsActionPerformed

    private void btnActActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnActActionPerformed
        // Proceso de inserción
        if (comprobarValidez()) {
            int respuesta = JOptionPane.showConfirmDialog(this,
                    "Actualizar los datos actuales",
                    "Actualizar registro",
                    JOptionPane.OK_CANCEL_OPTION,
                    JOptionPane.WARNING_MESSAGE);

            if (respuesta == JOptionPane.OK_OPTION) {
                try {
                    // Actualizar la fila actual
                    actualizarFila(rs);

                    // Actualizar interfaz
//                    actualizarInterfaz();
                } catch (SQLException e) {
                    JOptionPane.showMessageDialog(this,
                            "Actualización de datos cancelada");
                }
            }
        } else {
            JOptionPane.showMessageDialog(this, "Hay datos erróneos");
        }
    }//GEN-LAST:event_btnActActionPerformed

    private void btnAntActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAntActionPerformed
        try {
            if (rs.previous()) {
                actualizarInterfaz();
            }
        } catch (SQLException sqle) {
            System.out.println("Sig: " + sqle);
        }
    }//GEN-LAST:event_btnAntActionPerformed

    private void btnIniActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnIniActionPerformed
        try {
            if (rs.first()) {
                actualizarInterfaz();
            }
        } catch (SQLException sqle) {
            System.out.println("Ini: " + sqle);
        }
    }//GEN-LAST:event_btnIniActionPerformed

    private void lblFotoMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_lblFotoMouseClicked
        // Tamaño de escalado
        int ancho = 132;
        int alto = 176;

        // Dialogo selección imagen
        JFileChooser fc = new JFileChooser(carpetaIMG);
        fc.showOpenDialog(this);

        // Obtiene el fichero de la imagen seleccionada
        File fichSel = fc.getSelectedFile();

        // Si hay un fichero seleccionado
        if (fichSel != null) {
            // Memoriza la carpeta de la que se ha obtenido el fichero
            carpetaIMG = fichSel.getParentFile();

            // Obtiene la ruta completa del fichero
            String rutaFoto = fichSel.toString();

            // Imagen a partir de la ruta de la foto
            Image imagenIni = Toolkit.getDefaultToolkit().getImage(rutaFoto);

            // Crea una imagen escalada al tamaño deseado
            Image imagenEsc = imagenIni.getScaledInstance(ancho, alto,
                    Image.SCALE_AREA_AVERAGING);

            // Crea un objeto ImageIcon 
            Icon imagenICN = new ImageIcon(imagenEsc);

            // Actualiza la etiqueta de la foto
            alumno.setFoto(imagenICN);
        }
    }//GEN-LAST:event_lblFotoMouseClicked

    private void btnConDesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnConDesActionPerformed
        if (btnConDes.getText().equals("Conectar")) {
            // Muestra el diálogo de conexión
            dialogoCon.setVisible(true);

            //-- A partir de aquí se ejecuta cuando el dialogo se cierra
            //
            // Obtiene la referencia a la conexión
            con = dialogoCon.getConexion();

            // Analiza la conexión
            if (con != null) {
                // Cambia el rótulo del botón
                btnConDes.setText("Desconectar");

                // Crear acceso a los datos
                crearAccesoDatos();

                // Actualizar interfaz
                actualizarInterfaz();

                // Desbloquear interfaz
                accederInterfaz(true);
            }
        } else {
            // Desconecta la base de datos
            cerrarBD();

            // Cambia el rótulo del botón
            btnConDes.setText("Conectar");

            // Actualizar interfaz
            actualizarInterfaz();

            // Bloquear interfaz
            accederInterfaz(false);
        }
    }//GEN-LAST:event_btnConDesActionPerformed

    private void txfNifFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfNifFocusGained
        // Color de la letra en modo edición
        txfNif.setForeground(Color.BLACK);

        // Color de fondo de campo seleccionado
        txfNif.setBackground(Color.CYAN);
    }//GEN-LAST:event_txfNifFocusGained

    private void txfNombreFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfNombreFocusGained
        // Color de la letra en modo edición
        txfNombre.setForeground(Color.BLACK);

        // Color de fondo de campo seleccionado
        txfNombre.setBackground(Color.CYAN);
    }//GEN-LAST:event_txfNombreFocusGained

    private void txfApellidosFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfApellidosFocusGained
        // Color de la letra en modo edición
        txfApellidos.setForeground(Color.BLACK);

        // Color de fondo de campo seleccionado
        txfApellidos.setBackground(Color.CYAN);
    }//GEN-LAST:event_txfApellidosFocusGained

    private void txfNacFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfNacFocusGained
        // Color de la letra en modo edición
        txfNac.setForeground(Color.BLACK);

        // Color de fondo de campo seleccionado
        txfNac.setBackground(Color.CYAN);
    }//GEN-LAST:event_txfNacFocusGained

    private void txfTelefonoFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfTelefonoFocusGained
        // Color de la letra en modo edición
        txfTelefono.setForeground(Color.BLACK);

        // Color de fondo de campo seleccionado
        txfTelefono.setBackground(Color.CYAN);
    }//GEN-LAST:event_txfTelefonoFocusGained

    private void txfEMailFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfEMailFocusGained
        // Color de la letra en modo edición
        txfEMail.setForeground(Color.BLACK);

        // Color de fondo de campo seleccionado
        txfEMail.setBackground(Color.CYAN);
    }//GEN-LAST:event_txfEMailFocusGained

    private void txfDomicilioFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfDomicilioFocusGained
        // Color de la letra en modo edición
        txfDomicilio.setForeground(Color.BLACK);

        // Color de fondo de campo seleccionado
        txfDomicilio.setBackground(Color.CYAN);
    }//GEN-LAST:event_txfDomicilioFocusGained

    private void txfLocalidadFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfLocalidadFocusGained
        // Color de la letra en modo edición
        txfLocalidad.setForeground(Color.BLACK);

        // Color de fondo de campo seleccionado
        txfLocalidad.setBackground(Color.CYAN);
    }//GEN-LAST:event_txfLocalidadFocusGained

    private void txfProvinciaFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfProvinciaFocusGained
        // Color de la letra en modo edición
        txfProvincia.setForeground(Color.BLACK);

        // Color de fondo de campo seleccionado
        txfProvincia.setBackground(Color.CYAN);
    }//GEN-LAST:event_txfProvinciaFocusGained

    private void txfCPFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfCPFocusGained
        // Color de la letra en modo edición
        txfCP.setForeground(Color.BLACK);

        // Color de fondo de campo seleccionado
        txfCP.setBackground(Color.CYAN);
    }//GEN-LAST:event_txfCPFocusGained

    private void txfUserFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfUserFocusGained
        // Color de la letra en modo edición
        txfUser.setForeground(Color.BLACK);

        // Color de fondo de campo seleccionado
        txfUser.setBackground(Color.CYAN);
    }//GEN-LAST:event_txfUserFocusGained

    private void txfNifFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfNifFocusLost
        // Valida el campo
        nifOK = validarCampoTexto(txfNif, ER_NIF, "*");

        // Color de fondo de campo
        txfNif.setBackground(Color.WHITE);
    }//GEN-LAST:event_txfNifFocusLost

    private void txfNombreFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfNombreFocusLost
        // Valida el campo
        nombreOK = validarCampoTexto(txfNombre, ER_NOMBRE, "*");

        // Color de fondo de campo
        txfNombre.setBackground(Color.WHITE);
    }//GEN-LAST:event_txfNombreFocusLost

    private void txfApellidosFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfApellidosFocusLost
        // Valida el campo
        apellidosOK = validarCampoTexto(txfApellidos, ER_APELLIDOS, "*");

        // Color de fondo de campo
        txfApellidos.setBackground(Color.WHITE);
    }//GEN-LAST:event_txfApellidosFocusLost

    private void txfNacFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfNacFocusLost
        // Valida el campo
        nacOK = validarCampoTexto(txfNac, ER_NAC, "*");

        // Color de fondo de campo
        txfNac.setBackground(Color.WHITE);
    }//GEN-LAST:event_txfNacFocusLost

    private void txfTelefonoFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfTelefonoFocusLost
        // Valida el campo
        telefonoOK = validarCampoTexto(txfTelefono, ER_TELEFONO, "*");

        // Color de fondo de campo
        txfTelefono.setBackground(Color.WHITE);
    }//GEN-LAST:event_txfTelefonoFocusLost

    private void txfEMailFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfEMailFocusLost
        // Valida el campo
        emailOK = validarCampoTexto(txfEMail, ER_MAIL, "*");

        // Color de fondo de campo
        txfEMail.setBackground(Color.WHITE);
    }//GEN-LAST:event_txfEMailFocusLost

    private void txfDomicilioFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfDomicilioFocusLost
        // Valida el campo
        domicilioOK = validarCampoTexto(txfDomicilio, ER_DOMICILIO, "*");

        // Color de fondo de campo
        txfDomicilio.setBackground(Color.WHITE);
    }//GEN-LAST:event_txfDomicilioFocusLost

    private void txfLocalidadFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfLocalidadFocusLost
        // Valida el campo
        localidadOK = validarCampoTexto(txfLocalidad, ER_LOCALIDAD, "*");

        // Color de fondo de campo
        txfLocalidad.setBackground(Color.WHITE);
    }//GEN-LAST:event_txfLocalidadFocusLost

    private void txfProvinciaFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfProvinciaFocusLost
        // Valida el campo
        provinciaOK = validarCampoTexto(txfProvincia, ER_PROVINCIA, "*");

        // Color de fondo de campo
        txfProvincia.setBackground(Color.WHITE);
    }//GEN-LAST:event_txfProvinciaFocusLost

    private void txfCPFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfCPFocusLost
        // Valida el campo
        cpOK = validarCampoTexto(txfCP, ER_CP, "*");

        // Color de fondo de campo
        txfCP.setBackground(Color.WHITE);
    }//GEN-LAST:event_txfCPFocusLost

    private void txfUserFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfUserFocusLost
        // Valida el campo
        userOK = validarCampoTexto(txfUser, ER_USER, "*");

        // Color de fondo de campo
        txfUser.setBackground(Color.WHITE);
    }//GEN-LAST:event_txfUserFocusLost

    private void txfExpFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfExpFocusGained
        // Color de la letra en modo edición
        txfExp.setForeground(Color.BLACK);

        // Color de fondo de campo seleccionado
        txfExp.setBackground(Color.CYAN);
    }//GEN-LAST:event_txfExpFocusGained

    private void txfExpFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txfExpFocusLost
        // Valida el campo
        expOK = validarCampoTexto(txfExp, ER_EXP, "*");

        // Color de fondo de campo
        txfExp.setBackground(Color.WHITE);
    }//GEN-LAST:event_txfExpFocusLost

    private void sldRegActStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sldRegActStateChanged
        try {
            if (rs.absolute(sldRegAct.getValue())) {
                actualizarInterfaz();
            }
        } catch (SQLException sqle) {
            System.out.println("Sig: " + sqle);
        }
    }//GEN-LAST:event_sldRegActStateChanged

    private void pwfPassFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_pwfPassFocusGained
        // Color de la letra en modo edición
        pwfPass.setForeground(Color.BLACK);

        // Color de fondo de campo seleccionado
        pwfPass.setBackground(Color.CYAN);
    }//GEN-LAST:event_pwfPassFocusGained

    private void pwfPassFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_pwfPassFocusLost
        // Valida el campo
        passOK = validarCampoTexto(pwfPass, ER_PASS, "*");

        // Color de fondo de campo
        pwfPass.setBackground(Color.WHITE);
    }//GEN-LAST:event_pwfPassFocusLost

    public static void main(String args[]) {
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Windows".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(GestionAlumnos.class
                    .getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(GestionAlumnos.class
                    .getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(GestionAlumnos.class
                    .getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(GestionAlumnos.class
                    .getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new GestionAlumnos().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnAct;
    private javax.swing.JButton btnAnt;
    private javax.swing.JButton btnBor;
    private javax.swing.JButton btnConDes;
    private javax.swing.JButton btnFin;
    private javax.swing.JButton btnIni;
    private javax.swing.JButton btnIns;
    private javax.swing.JButton btnSig;
    private javax.swing.JLabel lblApellidos;
    private javax.swing.JLabel lblCP;
    private javax.swing.JLabel lblDomicilio;
    private javax.swing.JLabel lblEMail;
    private javax.swing.JLabel lblExp;
    private javax.swing.JLabel lblFoto;
    private javax.swing.JLabel lblLocalidad;
    private javax.swing.JLabel lblNac;
    private javax.swing.JLabel lblNif;
    private javax.swing.JLabel lblNombre;
    private javax.swing.JLabel lblNumReg;
    private javax.swing.JLabel lblPass;
    private javax.swing.JLabel lblProvincia;
    private javax.swing.JLabel lblRegAct;
    private javax.swing.JLabel lblTelefono;
    private javax.swing.JLabel lblUser;
    private javax.swing.JPanel pnlDomicilio;
    private javax.swing.JPanel pnlId;
    private javax.swing.JPanel pnlNavegacion;
    private javax.swing.JPanel pnlSeguridad;
    private javax.swing.JPasswordField pwfPass;
    private javax.swing.JSlider sldRegAct;
    private javax.swing.JTextField txfApellidos;
    private javax.swing.JTextField txfCP;
    private javax.swing.JTextField txfDomicilio;
    private javax.swing.JTextField txfEMail;
    private javax.swing.JTextField txfExp;
    private javax.swing.JTextField txfLocalidad;
    private javax.swing.JTextField txfNac;
    private javax.swing.JTextField txfNif;
    private javax.swing.JTextField txfNombre;
    private javax.swing.JTextField txfProvincia;
    private javax.swing.JTextField txfTelefono;
    private javax.swing.JTextField txfUser;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration//GEN-END:variables

    public Alumno getAlumno() {
        return alumno;
    }

    public void setAlumno(Alumno alumno) {
        this.alumno = alumno;
    }

    private void iniciarAnterior() {
        // Bean de enlace para los datos de los alumnos
        alumno = new Alumno();

        // Carpeta inicial de busqueda de imagenes
        carpetaIMG = new File(System.getProperty("user.dir"));
    }

    private void iniciarPosterior() {
        // Obtiene los objetos MouseListeners registrados sobre la imagen
        listaML = lblFoto.getMouseListeners();

        // Crea el dialogo de conexión - INVISIBLE
        dialogoCon = new DlgEnlaceBD(this, true);

        // Desactiva el acceso al interfaz
        accederInterfaz(false);
    }

    private void actualizarInterfaz() {
        try {
            // Actualizar datos interfaz
            importarModelo(alumno, rs);

            // Actualizar botones
            actualizarNavegador(rs);

            // Actualizar selector
            actualizarSelector(sldRegAct, lblNumReg, rs);
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    private void actualizarNavegador(ResultSet rs) throws Exception {
        // Obtener el número de filas
        int totFilas = calcularNumeroRegistros(rs);

        // Obtener la fila actual
        int filaAct = calcularPosicionActual(rs);

        // Discriminación
        if (con == null) {                        // Base de datos vacia
            btnAnt.setEnabled(false);
            btnIni.setEnabled(false);
            btnSig.setEnabled(false);
            btnFin.setEnabled(false);
            btnBor.setEnabled(false);
            btnAct.setEnabled(false);
            btnIns.setEnabled(false);
            sldRegAct.setEnabled(false);
            lblRegAct.setEnabled(false);
            lblNumReg.setEnabled(false);
        } else if (totFilas == 0) {              // Base de datos vacia
            btnAnt.setEnabled(false);
            btnIni.setEnabled(false);
            btnSig.setEnabled(false);
            btnFin.setEnabled(false);
            btnBor.setEnabled(false);
            btnAct.setEnabled(false);
            btnIns.setEnabled(true);
            sldRegAct.setEnabled(false);
            lblRegAct.setEnabled(false);
            lblNumReg.setEnabled(false);
        } else if (totFilas == 1) {                 // Un sólo registro
            btnAnt.setEnabled(false);
            btnIni.setEnabled(false);
            btnSig.setEnabled(false);
            btnFin.setEnabled(false);
            btnBor.setEnabled(true);
            btnAct.setEnabled(true);
            btnIns.setEnabled(true);
            sldRegAct.setEnabled(false);
            lblRegAct.setEnabled(false);
            lblNumReg.setEnabled(false);
        } else if (filaAct == 1) {                  // Primer registro
            btnAnt.setEnabled(false);
            btnIni.setEnabled(false);
            btnSig.setEnabled(true);
            btnFin.setEnabled(true);
            btnBor.setEnabled(true);
            btnAct.setEnabled(true);
            btnIns.setEnabled(true);
            sldRegAct.setEnabled(true);
            lblRegAct.setEnabled(true);
            lblNumReg.setEnabled(true);
        } else if (filaAct == totFilas) {          // ültimo registro
            btnAnt.setEnabled(true);
            btnIni.setEnabled(true);
            btnSig.setEnabled(false);
            btnFin.setEnabled(false);
            btnBor.setEnabled(true);
            btnAct.setEnabled(true);
            btnIns.setEnabled(true);
            sldRegAct.setEnabled(true);
            lblRegAct.setEnabled(true);
            lblNumReg.setEnabled(true);
        } else {                                       // Registro intermedio
            btnAnt.setEnabled(true);
            btnIni.setEnabled(true);
            btnSig.setEnabled(true);
            btnFin.setEnabled(true);
            btnBor.setEnabled(true);
            btnAct.setEnabled(true);
            btnIns.setEnabled(true);
            sldRegAct.setEnabled(true);
            lblRegAct.setEnabled(true);
            lblNumReg.setEnabled(true);
        }
    }

    private void actualizarSelector(JSlider sldActual, JLabel lblActual,
            ResultSet rs) throws Exception {
        // Obtener el número de filas
        int totFilas = calcularNumeroRegistros(rs);

        // Obtener la fila actual
        int filaAct = calcularPosicionActual(rs);

        // Guarda los gestores de eventos
        ChangeListener[] lista = sldActual.getChangeListeners();

        // Desconecta los ChangeListener definidos en tiempo de diseño
        // Pero no los BeanBinding - Si se desconectan todos en enlazado
        // NO FUNCIONA
        for (ChangeListener cl : lista) {
            // Obtiene la representación de texto del Listener
            String texto = cl.toString();

            // Ignora el listener si es BeanBinding
            if (!texto.contains("org.jdesktop")) {
                sldActual.removeChangeListener(cl);
            }
        }

        // Analiza el estado del deslizador
        if (totFilas > 0) {
            // Deslizador
            sldActual.setEnabled(true);
            sldActual.setMinimum(1);          // Change Listeners notificados
            sldActual.setMaximum(totFilas);   // Change Listeners notificados
            sldActual.setValue(filaAct);      // Change Listeners notificados

            // Total de registros
            lblActual.setText(totFilas + "");
        } else {

            // Deslizador
            sldActual.setEnabled(false);
            sldActual.setMinimum(0);          // Change Listeners notificados
            sldActual.setMaximum(0);          // Change Listeners notificados
            sldActual.setValue(0);            // Change Listeners notificados

            // Total de registros
            lblActual.setText("0");
        }

        // Conecta los ChangeListener desconectados
        for (ChangeListener cl : lista) {
            // Obtiene la representación de texto del Listener
            String texto = cl.toString();

            // Ignora el listener si es BeanBinding
            if (!texto.contains("org.jdesktop")) {
                sldActual.addChangeListener(cl);
            }
        }
    }

    private boolean validarCampoTexto(JTextField txfActual, String expReg,
            String textoCampoVacio) throws PatternSyntaxException {
        // Semáforo de validación
        boolean validacionOK = false;

        try {
            // Obtiene el texto del campo
            String textoActual = txfActual.getText().trim();

            // Comprueba campo vacio
            if (textoActual.equals("")) {
                textoActual = textoCampoVacio;
            }

            // Restaura el texto formateado
            txfActual.setText(textoActual);

            // Patrón de la expresión regular
            Pattern patron = Pattern.compile(expReg);

            // Aplica el patrón al texto de prueba
            Matcher detector = patron.matcher(textoActual);

            // Comprueba la coincidencia
            if (detector.matches()) {
                // Contenido correcto
                txfActual.setForeground(Color.BLACK);

                // Actualiza el semáforo
                validacionOK = true;
            } else {
                // Contenido problemático
                txfActual.setForeground(Color.RED);
            }
        } catch (PatternSyntaxException pse) {
            // Contenido problemático
            txfActual.setForeground(Color.RED);

            // Expresión regular errónea - Depurar expresión
            JOptionPane.showMessageDialog(this, "Expresión regular errónea");
        }

        // Devuelve el resultado de la validacion
        return validacionOK;
    }

    private boolean comprobarValidez() {
        expOK = validarCampoTexto(txfExp, ER_EXP, "*");
        nombreOK = validarCampoTexto(txfNombre, ER_NOMBRE, "*");
        apellidosOK = validarCampoTexto(txfApellidos, ER_APELLIDOS, "*");
        nacOK = validarCampoTexto(txfNac, ER_NAC, "*");
        nifOK = validarCampoTexto(txfNif, ER_NIF, "*");
        telefonoOK = validarCampoTexto(txfTelefono, ER_TELEFONO, "*");
        emailOK = validarCampoTexto(txfEMail, ER_MAIL, "*");
        domicilioOK = validarCampoTexto(txfDomicilio, ER_DOMICILIO, "*");
        localidadOK = validarCampoTexto(txfLocalidad, ER_LOCALIDAD, "*");
        provinciaOK = validarCampoTexto(txfProvincia, ER_PROVINCIA, "*");
        cpOK = validarCampoTexto(txfCP, ER_CP, "*");
        userOK = validarCampoTexto(txfUser, ER_USER, "*");
        passOK = validarCampoTexto(pwfPass, ER_PASS, "*");

        return expOK && nombreOK && apellidosOK && nacOK && nifOK
                && telefonoOK && emailOK && domicilioOK && localidadOK
                && provinciaOK && cpOK && userOK && passOK;
    }

    private void accederInterfaz(boolean accesoOK) {
        txfExp.setEnabled(accesoOK);
        txfNombre.setEnabled(accesoOK);
        txfApellidos.setEnabled(accesoOK);
        txfNif.setEnabled(accesoOK);
        txfNac.setEnabled(accesoOK);
        txfTelefono.setEnabled(accesoOK);
        txfEMail.setEnabled(accesoOK);
        txfDomicilio.setEnabled(accesoOK);
        txfLocalidad.setEnabled(accesoOK);
        txfProvincia.setEnabled(accesoOK);
        txfCP.setEnabled(accesoOK);
        txfUser.setEnabled(accesoOK);
        pwfPass.setEnabled(accesoOK);

        lblFoto.setEnabled(accesoOK);
        if (accesoOK) {
            // Si la foto no tiene listeners registra listeners
            if (lblFoto.getMouseListeners().length == 0) {
                for (MouseListener listaML1 : listaML) {
                    lblFoto.addMouseListener(listaML1);
                }
            }
        } else {
            for (MouseListener listaML1 : listaML) {
                lblFoto.removeMouseListener(listaML1);
            }
        }
    }

    private int calcularNumeroRegistros(ResultSet rs) {
        // Variable para almacenar el resultado
        int numFilas;

        try {
            // Número de la fila a la que apunta el cursor
            int filaAct = rs.getRow();

            // Va al final del ResultSet
            rs.last();

            // Obtiene el número de filas
            numFilas = rs.getRow();

            if (filaAct != 0) {
                // Coloca el cursor en la posición previa
                rs.absolute(filaAct);
            } else {
                // Coloca el cursor al principio del ResultSet
                rs.first();
            }
        } catch (SQLException | NullPointerException e) {
            numFilas = 0;
        }

        // Devuelve el número de filas calculadas
        return numFilas;
    }

    private void borrarFila(ResultSet rs) throws Exception {
        // Borra la fila actual
        rs.deleteRow();

        // Va a la primera fila
        rs.first();
    }

    public void importarModelo(Alumno alumno, ResultSet rs) throws Exception {
        // Obtener el número de filas
        int totFilas = calcularNumeroRegistros(rs);

        if (totFilas > 0) {
            // Campos de texto
            alumno.setExp(rs.getString("exp"));
            alumno.setNombre(rs.getString("nombre"));
            alumno.setApellidos(rs.getString("apellidos"));
            alumno.setNif(rs.getString("nif"));
            alumno.setTelefono(rs.getString("telefono"));
            alumno.setEmail(rs.getString("email"));
            alumno.setDomicilio(rs.getString("domicilio"));
            alumno.setLocalidad(rs.getString("localidad"));
            alumno.setProvincia(rs.getString("provincia"));
            alumno.setCp(rs.getString("cp"));
            alumno.setUser(rs.getString("user"));
            alumno.setPass(rs.getString("pass"));

            // Fecha de nacimiento
            SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
            java.sql.Date fecha = rs.getDate("nac");
            alumno.setNac(sdf.format(fecha));

            // Proceso de transferencia
            try (InputStream is = rs.getBinaryStream("foto")) {
                if (is != null) {
                    // Definición de cauces para realizar la transferencia
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();

                    // Proceso de transferencia
                    byte[] buffer = new byte[8096];
                    boolean finLectura = false;
                    do {
                        // Lee del origen
                        int numBytesLeidos = is.read(buffer);

                        // Escribe en el destino
                        if (numBytesLeidos > 0) {
                            baos.write(buffer, 0, numBytesLeidos);
                        } else {
                            finLectura = true;
                        }
                    } while (finLectura == false);

                    // Actualiza la columna con la foto
                    alumno.setFoto(new ImageIcon(baos.toByteArray()));
                }
            }
        } else {
            inicializarEntidad();
        }
    }

    private void insertarFila(ResultSet rs) throws SQLException {
        // Situar la fila de inserción
        rs.moveToInsertRow();

        // Actualiza la fila con los datos del interfaz
        rs.updateString("exp", alumno.getExp());
        rs.updateString("nombre", alumno.getNombre());
        rs.updateString("apellidos", alumno.getApellidos());
        rs.updateString("nif", alumno.getNif());
        rs.updateString("telefono", alumno.getTelefono());
        rs.updateString("email", alumno.getEmail());
        rs.updateString("domicilio", alumno.getDomicilio());
        rs.updateString("localidad", alumno.getLocalidad());
        rs.updateString("provincia", alumno.getProvincia());
        rs.updateString("cp", alumno.getCp());
        rs.updateString("user", alumno.getUser());
        rs.updateString("pass", alumno.getPass());

        try {
            SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
            java.util.Date fechaNacUtil = sdf.parse(alumno.getNac());
            java.sql.Date fechaNacSQL = new Date(fechaNacUtil.getTime());
            rs.updateDate("nac", fechaNacSQL);
        } catch (ParseException ex) {
            java.util.Date fechaNacUtil = new java.util.Date();
            java.sql.Date fechaNacSQL = new Date(fechaNacUtil.getTime());
            rs.updateDate("nac", fechaNacSQL);
        }

        try {
            // Definición de cauces para realizar la actualización
            ImageIcon ii = (ImageIcon) alumno.getFoto();
            if (ii != null) {
                /*
                 * Achtung: Pues resulta que el método getImage dice que devuelve un
                 * objeto java.awt.image pero parece ser que devuelve un objeto
                 * sun.awt.image.ToolkitImage, lo que supongo que es un error interno de
                 * Cast. Por eso hay que hacer la martingala del Cast de la siguiente
                 * intrucción. El objetivo es obtener un cauce binario a partir de la
                 * imagen guardada en el objeto ImageIcon
                 */
                ToolkitImage i = (ToolkitImage) ii.getImage();
                BufferedImage bi = i.getBufferedImage();
                ByteArrayInputStream bais;
                /*
                 * El método estático write de la siguiente instrucción permite volcar
                 * los datos de un cauce binario de entrada a un cauce binario de
                 * salida. Esté método estático tiene un parámetro central que no se si
                 * es decorativo o no y que representa el "Nombre informal del formato
                 * gráfico del archivo"
                 */
                try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
                    /*
                     * El método estático write de la siguiente instrucción permite volcar
                     * los datos de un cauce binario de entrada a un cauce binario de
                     * salida. Esté método estático tiene un parámetro central que no se si
                     * es decorativo o no y que representa el "Nombre informal del formato
                     * gráfico del archivo"
                     */
                    ImageIO.write(bi, "png", baos);
                    bais = new ByteArrayInputStream(baos.toByteArray());
                    rs.updateBinaryStream("foto", bais, baos.size());
                    /*
                     * Sin instrucciones siguientes de cierre esto no furrula.
                     */
                    baos.flush();
                }
                bais.close();
            }
        } catch (IOException ex) {
            System.out.println(ex);
        }

        // Insertar la fila
        rs.insertRow();

        // Sale de la zona de inserción a la zona previa
        rs.moveToCurrentRow();
    }

    public void cerrarBD() {
        // Cierra el ResultSet
        try {
            if (rs != null) {
                rs.close();
                rs = null;
            }
        } catch (SQLException | NullPointerException e) {
            Logger.getLogger(GestionAlumnos.class.getName()).log(Level.SEVERE, null, e);
        }

        // Cierra el Statement
        try {
            if (stmt != null) {
                stmt.close();
                stmt = null;
            }
        } catch (SQLException | NullPointerException e) {
            Logger.getLogger(GestionAlumnos.class.getName()).log(Level.SEVERE, null, e);
        }

        // Cierra la conexión
        try {
            if (con != null) {
                con.close();
                con = null;
            }
        } catch (SQLException | NullPointerException e) {
            Logger.getLogger(GestionAlumnos.class.getName()).log(Level.SEVERE, null, e);
        }
    }

    private void actualizarFila(ResultSet rs) throws SQLException {
        // Actualiza la fila con los datos del interfaz
        rs.updateString("exp", alumno.getExp());
        rs.updateString("nombre", alumno.getNombre());
        rs.updateString("apellidos", alumno.getApellidos());
        rs.updateString("nif", alumno.getNif());
        rs.updateString("telefono", alumno.getTelefono());
        rs.updateString("email", alumno.getEmail());
        rs.updateString("domicilio", alumno.getDomicilio());
        rs.updateString("localidad", alumno.getLocalidad());
        rs.updateString("provincia", alumno.getProvincia());
        rs.updateString("cp", alumno.getCp());
        rs.updateString("user", alumno.getUser());
        rs.updateString("pass", alumno.getPass());

        try {
            SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
            java.util.Date fechaNacUtil = sdf.parse(alumno.getNac());
            java.sql.Date fechaNacSQL = new Date(fechaNacUtil.getTime());
            rs.updateDate("nac", fechaNacSQL);
        } catch (ParseException ex) {
            java.util.Date fechaNacUtil = new java.util.Date();
            java.sql.Date fechaNacSQL = new Date(fechaNacUtil.getTime());
            rs.updateDate("nac", fechaNacSQL);
        }

        try {
            // Definición de cauces para realizar la actualización
            ImageIcon ii = (ImageIcon) alumno.getFoto();
            if (ii != null) {
                /*
                 * Achtung: Pues resulta que el método getImage dice que devuelve un
                 * objeto java.awt.image pero parece ser que devuelve un objeto
                 * sun.awt.image.ToolkitImage, lo que supongo que es un error interno de
                 * Cast. Por eso hay que hacer la martingala del Cast de la siguiente
                 * intrucción. El objetivo es obtener un cauce binario a partir de la
                 * imagen guardada en el objeto ImageIcon
                 */
                ToolkitImage i = (ToolkitImage) ii.getImage();
                BufferedImage bi = i.getBufferedImage();
                ByteArrayInputStream bais;
                /*
                 * El método estático write de la siguiente instrucción permite volcar
                 * los datos de un cauce binario de entrada a un cauce binario de
                 * salida. Esté método estático tiene un parámetro central que no se si
                 * es decorativo o no y que representa el "Nombre informal del formato
                 * gráfico del archivo"
                 */
                try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
                    /*
                     * El método estático write de la siguiente instrucción permite volcar
                     * los datos de un cauce binario de entrada a un cauce binario de
                     * salida. Esté método estático tiene un parámetro central que no se si
                     * es decorativo o no y que representa el "Nombre informal del formato
                     * gráfico del archivo"
                     */
                    ImageIO.write(bi, "png", baos);
                    bais = new ByteArrayInputStream(baos.toByteArray());
                    rs.updateBinaryStream("foto", bais, baos.size());
                    /*
                     * Sin instrucciones siguientes de cierre esto no furrula.
                     */
                    baos.flush();
                }
                bais.close();
            }
        } catch (IOException ex) {
            System.out.println(ex);
        }

        // Actualiza la fila actual
        rs.updateRow();
    }

    private void crearAccesoDatos() {
        try {
            // ---- CAMBIOS DE DATOS ----
            // ResultSet.TYPE_FORWARD_ONLY (*) - Indica que el objeto ResultSet se 
            //      puede recorrer unicamente hacia adelante.
            // ResultSet.TYPE_SCROLL_INSENSITIVE - Indica que el objeto ResultSet se 
            //      puede recorrer, pero en general no es sensible a los cambios en 
            //      los datos que subyacen en él.
            // ResultSet.TYPE_SCROLL_SENSITIVE - Indica que el objeto ResultSet se 
            //      puede recorrer, y además, los cambios en él repercuten
            //      en la base de datos subyacente.
            // ---- MODOS DE CONCURRENCIA ----
            // ResultSet.CONCUR_READ_ONLY (*) - Indica que en el modo de concurrencia 
            //      para el objeto ResultSet éste no puede ser actualizado.
            // ResultSet.CONCUR_UPDATABLE - Indica que en el modo de concurrencia 
            //      para el objeto ResultSet éste podria ser actualizado.
            //
            // Crear una sentencia
            stmt = con.createStatement(
                    ResultSet.TYPE_SCROLL_SENSITIVE,
                    ResultSet.CONCUR_UPDATABLE);

            // Sentencia SQL para la consulta
            final String SQL = "SELECT * FROM Alumno";

            // Obtener los resultados de la consulta
            rs = stmt.executeQuery(SQL);
        } catch (SQLException e) {
            // Información de depuración
            Logger.getLogger(GestionAlumnos.class.getName()).log(Level.SEVERE, null, e);

            // Cierra la base de datos
            cerrarBD();

            // Finaliza el programa
            terminarPrograma();
        }
    }

    private void terminarPrograma() {
        setVisible(false);
        dispose();
        System.exit(0);
    }

    private void inicializarEntidad() {
        try {
            // Crea un alumno vacío
            Alumno alumnoTmp = new Alumno();

            // Limpia los controles de datos
            BeanUtils.copyProperties(alumno, alumnoTmp);
        } catch (IllegalAccessException | InvocationTargetException e) {
            System.out.println(e);
        }
    }

    private int calcularPosicionActual(ResultSet rs) {
        int filaActual;

        try {
            filaActual = rs.getRow();
        } catch (SQLException | NullPointerException e) {
            filaActual = 0;
        }

        return filaActual;
    }
}
